package cn.iocoder.yudao.module.reading.util;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.reading.enums.FilePathConstants;

/**
 * 文件路径工具类
 * 提供业务相关的文件路径生成方法
 * 
 * @author 李晨
 */
public class FilePathUtils {

    // =============================================
    // 用户相关文件路径生成
    // =============================================
    
    /**
     * 生成用户头像文件路径
     * 
     * @param userId 用户ID
     * @param fileName 原始文件名
     * @return 用户头像存储路径
     */
    public static String generateUserAvatarPath(Long userId, String fileName) {
        return generateBusinessPath(FilePathConstants.USER_AVATAR_PATH, userId, fileName);
    }
    
    /**
     * 生成用户配音文件目录路径
     *
     * @param userId 用户ID
     * @param bookId 绘本ID
     * @param pageId 页面ID
     * @param fileName 原始文件名
     * @return 用户配音文件存储目录路径
     */
    public static String generateUserRecordingPath(Long userId, Long bookId, Long pageId, String fileName) {
        // 按照规范生成目录路径：users/recordings/{userId}/{bookId}/{pageId}/
        // 注意：日期前缀由FileServiceImpl统一处理，这里不再添加日期目录

        // 生成目录路径：users/recordings/{userId}/{bookId}/{pageId}
        String subPath = userId.toString() + "/" + bookId.toString() + "/" + pageId.toString();
        return FilePathConstants.USER_RECORDING_PATH + "/" + subPath;
    }

    /**
     * 生成用户配音文件名
     *
     * @param originalFileName 原始文件名
     * @return 新的文件名：recording_{时间戳}.{扩展名}
     */
    public static String generateUserRecordingFileName(String originalFileName) {
        String timestamp = String.valueOf(System.currentTimeMillis());

        // 获取文件扩展名
        String extension = getFileExtension(originalFileName);
        if (extension.isEmpty()) {
            extension = "mp3"; // 默认扩展名
        }

        // 生成新文件名：recording_{时间戳}.{扩展名}
        return "recording_" + timestamp + "." + extension;
    }

    // =============================================
    // 绘本相关文件路径生成
    // =============================================
    
    /**
     * 生成绘本封面文件路径
     * 
     * @param bookSetId 绘本集ID
     * @param bookId 绘本ID
     * @param fileName 原始文件名
     * @return 绘本封面存储路径
     */
    public static String generateBookCoverPath(Long bookSetId, Long bookId, String fileName) {
        String subPath = "set-" + bookSetId + "/book-" + bookId;
        return FilePathConstants.BOOK_COVER_PATH + "/" + subPath;
    }
    
    /**
     * 生成绘本页面图片文件路径
     * 
     * @param bookSetId 绘本集ID
     * @param bookId 绘本ID
     * @param pageNumber 页码
     * @param fileName 原始文件名
     * @return 绘本页面图片存储路径
     */
    public static String generateBookPagePath(Long bookSetId, Long bookId, Integer pageNumber, String fileName) {
        String subPath = "set-" + bookSetId + "/book-" + bookId + "/page-" + pageNumber;
        return FilePathConstants.BOOK_PAGE_PATH + "/" + subPath;
    }
    
    /**
     * 生成绘本音频文件路径
     * 
     * @param bookSetId 绘本集ID
     * @param bookId 绘本ID
     * @param pageNumber 页码（可选）
     * @param fileName 原始文件名
     * @return 绘本音频文件存储路径
     */
    public static String generateBookAudioPath(Long bookSetId, Long bookId, Integer pageNumber, String fileName) {
        String subPath = "set-" + bookSetId + "/book-" + bookId;
        if (pageNumber != null) {
            subPath += "/page-" + pageNumber;
        }
        return FilePathConstants.BOOK_AUDIO_PATH + "/" + subPath;
    }

    // =============================================
    // 绘本集相关文件路径生成
    // =============================================
    
    /**
     * 生成绘本集封面文件路径
     * 
     * @param bookSetId 绘本集ID
     * @param fileName 原始文件名
     * @return 绘本集封面存储路径
     */
    public static String generateBookSetCoverPath(Long bookSetId, String fileName) {
        return generateBusinessPath(FilePathConstants.BOOK_SET_COVER_PATH, bookSetId, fileName);
    }

    // =============================================
    // 音频资源文件路径生成
    // =============================================
    
    /**
     * 生成音频资源文件路径
     * 
     * @param category 音频分类
     * @param language 语言类型
     * @param fileName 原始文件名
     * @return 音频资源存储路径
     */
    public static String generateAudioResourcePath(String category, String language, String fileName) {
        String subPath = category;
        if (StrUtil.isNotEmpty(language)) {
            subPath += "/" + language;
        }
        return FilePathConstants.AUDIO_RESOURCE_PATH + "/" + subPath;
    }
    
    /**
     * 生成音频封面文件路径
     * 
     * @param audioId 音频ID
     * @param fileName 原始文件名
     * @return 音频封面存储路径
     */
    public static String generateAudioCoverPath(Long audioId, String fileName) {
        return generateBusinessPath(FilePathConstants.AUDIO_COVER_PATH, audioId, fileName);
    }

    // =============================================
    // 系统文件路径生成
    // =============================================
    
    /**
     * 生成临时文件路径
     * 
     * @param fileName 原始文件名
     * @return 临时文件存储路径
     */
    public static String generateTempFilePath(String fileName) {
        return FilePathConstants.SYSTEM_TEMP_PATH;
    }
    
    /**
     * 生成导出文件路径
     * 
     * @param exportType 导出类型
     * @param fileName 原始文件名
     * @return 导出文件存储路径
     */
    public static String generateExportFilePath(String exportType, String fileName) {
        return FilePathConstants.SYSTEM_EXPORT_PATH + "/" + exportType;
    }

    // =============================================
    // 通用工具方法
    // =============================================
    
    /**
     * 生成业务相关的文件路径
     * 
     * @param basePath 基础路径
     * @param businessId 业务ID
     * @param fileName 原始文件名
     * @return 完整的业务文件路径
     */
    private static String generateBusinessPath(String basePath, Long businessId, String fileName) {
        return basePath + "/" + businessId;
    }
    
    /**
     * 验证文件路径是否合法
     * 
     * @param filePath 文件路径
     * @return 是否合法
     */
    public static boolean isValidFilePath(String filePath) {
        if (StrUtil.isEmpty(filePath)) {
            return false;
        }
        
        // 检查是否包含非法字符
        String[] illegalChars = {"../", "..\\", "<", ">", "|", "\"", "?", "*"};
        for (String illegalChar : illegalChars) {
            if (filePath.contains(illegalChar)) {
                return false;
            }
        }
        
        return true;
    }
    
    /**
     * 清理文件名，移除非法字符
     * 
     * @param fileName 原始文件名
     * @return 清理后的文件名
     */
    public static String sanitizeFileName(String fileName) {
        if (StrUtil.isEmpty(fileName)) {
            return fileName;
        }
        
        // 移除或替换非法字符
        return fileName.replaceAll("[<>:\"|?*]", "_")
                      .replaceAll("[\\\\/]", "_")
                      .trim();
    }
    
    /**
     * 获取文件扩展名
     * 
     * @param fileName 文件名
     * @return 文件扩展名（不包含点号）
     */
    public static String getFileExtension(String fileName) {
        if (StrUtil.isEmpty(fileName)) {
            return "";
        }
        
        int lastDotIndex = fileName.lastIndexOf('.');
        if (lastDotIndex > 0 && lastDotIndex < fileName.length() - 1) {
            return fileName.substring(lastDotIndex + 1).toLowerCase();
        }
        
        return "";
    }
    
    /**
     * 根据MIME类型获取推荐的文件扩展名
     * 
     * @param mimeType MIME类型
     * @return 推荐的文件扩展名
     */
    public static String getRecommendedExtension(String mimeType) {
        if (StrUtil.isEmpty(mimeType)) {
            return "";
        }
        
        switch (mimeType.toLowerCase()) {
            case "image/jpeg":
            case "image/jpg":
                return "jpg";
            case "image/png":
                return "png";
            case "image/gif":
                return "gif";
            case "image/webp":
                return "webp";
            case "audio/mpeg":
            case "audio/mp3":
                return "mp3";
            case "audio/wav":
                return "wav";
            case "audio/ogg":
                return "ogg";
            case "audio/aac":
                return "aac";
            case "audio/m4a":
                return "m4a";
            default:
                return "";
        }
    }
}
